const axios = require('axios');
const jwt = require('jsonwebtoken');
const { atob } = require('base64-js');

async function test(identityToken) {
  const clientId = 'com.xxx.xxxx';
  // 解析 id_token
  const json = parserIdentityToken(identityToken);
  const header = json.header;
  const kid = header.kid;
  // 根据 kid，获取相应的公钥
  const publicKey = await getPublicKey(kid);
  if (!publicKey) {
    console.error(`[苹果登录失败 publicKey获取失败 clientId<${clientId}> kid<${kid}>]`);
    return;
  }
  getAppleUserId(clientId, publicKey, identityToken);
}

function getAppleUserId(appleClientId, publicKey, identityToken) {
  const appleIssuerUrl = 'https://appleid.apple.com';
  const jwtParser = jwt.verify(identityToken, publicKey, {
    issuer: appleIssuerUrl,
    audience: appleClientId,
  });
  if (jwtParser) {
    const { iss, sub, aud, exp } = jwtParser;
    console.log(`[苹果登录iss<${iss}> sub<${sub}> aud<${aud}> exp<${exp}>]`);
    if (appleIssuerUrl === iss && appleClientId === aud) {
      console.error(`[苹果账号登录成功 appleClientId<${appleClientId}> userId<${sub}>]`);
      return { userId: sub };
    }
  }
  return null;
}

function parserIdentityToken(identityToken) {
  const [deHeader, dePayload] = identityToken.split('.').map((part) => JSON.parse(atob(part)));
  return {
    header: deHeader,
    payload: dePayload,
  };
}

async function getPublicKey(kid) {
  const appleKeys = await getAppleKeys();
  try {
    const key = appleKeys[kid];
    const modulus = Buffer.from(key.n, 'base64');
    const exponent = Buffer.from(key.e, 'base64');
    return {
      kty: 'RSA',
      n: modulus.toString('base64'),
      e: exponent.toString('base64'),
    };
  } catch (error) {
    console.error(`getPublicKey error: ${error}`);
  }
  return null;
}

async function getAppleKeys() {
  const response = await axios.get('https://appleid.apple.com/auth/keys');
  const keys = response.data.keys;
  const result = {};
  keys.forEach((key) => {
    result[key.kid] = {
      n: key.n,
      e: key.e,
    };
  });
  return result;
}